package com.st.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mysql.cj.util.StringUtils;
import com.st.common.constant.ProductConstant;
import com.st.mall.product.dao.AttrAttrgroupRelationDao;
import com.st.mall.product.dao.AttrDao;
import com.st.mall.product.dao.CategoryDao;
import com.st.mall.product.entity.AttrAttrgroupRelationEntity;
import com.st.mall.product.entity.AttrEntity;
import com.st.mall.product.entity.CategoryEntity;
import com.st.mall.product.service.AttrService;
import com.st.mall.product.vo.AttrGroupEntityVo;
import com.st.mall.product.vo.AttrGroupResVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.st.common.utils.PageUtils;
import com.st.common.utils.Query;

import com.st.mall.product.dao.AttrGroupDao;
import com.st.mall.product.entity.AttrGroupEntity;
import com.st.mall.product.service.AttrGroupService;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private AttrAttrgroupRelationDao aardao;
    @Autowired
    private AttrDao adao;
    @Autowired
    private AttrGroupDao attrGroupDao;
    @Autowired
    private AttrService attrService;

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long cateLogId) {
        String key = (String) params.get("key");
        QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<AttrGroupEntity>();
        //如果key不为空，添加模糊查询条件
        if (!StringUtils.isNullOrEmpty(key)) {
            wrapper.and((obj) -> {
                obj.eq("attr_group_id", key).or().like("attr_group_name", key);
            });
        }
        IPage<AttrGroupEntity> page;
        //分类id不为0，进行拼上cateLogId
        if (!cateLogId.equals(0L)) {
            wrapper.eq("catelog_id", cateLogId);
        }
        page = this.page(new Query<AttrGroupEntity>().getPage(params),
                wrapper
        );
        return new PageUtils(page);
    }

    /**
     * @param attrGroupId 品牌分类id
     * @return 分类完整路径
     */
    public Long[] getCtLogPath(Long attrGroupId) {
        List<Long> list = new ArrayList<>();
        list.add(attrGroupId);
        List<CategoryEntity> categoryEntities = categoryDao.selectList(new QueryWrapper<CategoryEntity>());
        //在调用 findFirst 时，Stream 会对元素进行逐个处理，直到找到满足条件的第一个元素为止，之后就会立即停止处理并返回结果。
        Optional<CategoryEntity> first = categoryEntities.stream()
                .filter(entity -> entity.getCatId().equals(attrGroupId) && !entity.getParentCid().equals(0L))
                .findFirst();
        // ifPresent，用于在 Optional 对象不为空时执行一个操作。如果 Optional 对象为空，则不执行任何操作。
        first.ifPresent(entity -> {
            list.add(entity.getParentCid());
            categoryEntities.stream()
                    .filter(parent -> parent.getCatId().equals(list.get(list.size() - 1)) && !parent.getParentCid().equals(0L))
                    .findFirst()
                    .ifPresent(parent -> list.add(parent.getParentCid()));
        });
        Collections.reverse(list);
        return list.toArray(new Long[0]);
    }

    @Override
    public List<AttrEntity> getRelation(Long attrgroupId) {
        //查出关系表对应的attrid
        List<AttrAttrgroupRelationEntity> attrGroupIdList = aardao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .eq("attr_group_id", attrgroupId));
        List<AttrEntity> entityList = new ArrayList<>();
        //去attr表查详细信息
        if (attrGroupIdList.size() > 0) {
            attrGroupIdList.forEach(list -> {
                entityList.add(adao.selectById(list.getAttrId()));
            });
        }
        return entityList;
    }

    @Override
    public void saveRelation(List<AttrGroupEntityVo> attrGroup) {
        List<AttrAttrgroupRelationEntity> collect = attrGroup.stream().map(item -> {
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            BeanUtils.copyProperties(item, relationEntity);
            return relationEntity;
        }).collect(Collectors.toList());
        collect.forEach(relation -> {
            aardao.insert(relation);
        });
    }


    @Override
    public PageUtils getNoAttr(Map<String, Object> params, Long attrgroupId) {
        //1、当前分组只能关联自己所属的分类里面的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        //2、当前分组只能关联别的分组没有引用的属性
        //2.1)、当前分类下的其他分组
        List<AttrGroupEntity> group = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        List<Long> collect = group.stream().map(item -> {
            return item.getAttrGroupId();
        }).collect(Collectors.toList());

        //2.2)、这些分组关联的属性
        List<AttrAttrgroupRelationEntity> groupId = aardao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", collect));
        List<Long> attrIds = groupId.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        //2.3)、从当前分类的所有属性中移除这些属性；
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type", ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());
        if (attrIds != null && attrIds.size() > 0) {
            wrapper.notIn("attr_id", attrIds);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isNullOrEmpty(key)) {
            wrapper.and((w) -> {
                w.eq("attr_id", key).or().like("attr_name", key);
            });
        }
        IPage<AttrEntity> page = attrService.page(new Query<AttrEntity>().getPage(params), wrapper);

        return new PageUtils(page);
    }


    @Override
    public void deleteRelation(AttrGroupEntityVo vo) {
        if (vo.getAttrGroupId() != null && vo.getAttrId() != null) {
            aardao.delete(new QueryWrapper<AttrAttrgroupRelationEntity>()
                    .lambda().eq(AttrAttrgroupRelationEntity::getAttrGroupId, vo.getAttrGroupId())
                    .and(entity -> {
                        entity.eq(AttrAttrgroupRelationEntity::getAttrId, vo.getAttrId());
                    }));
        }
    }

    @Override
    public List<AttrGroupResVo> getWithAttr(Long catelogId) {
        //查出分类下分组
        List<AttrGroupEntity> attrGroupEntities = attrGroupDao
                .selectList(new LambdaQueryWrapper<AttrGroupEntity>()
                        .eq(AttrGroupEntity::getCatelogId, catelogId));
        //查分类和属性关联表
        List<AttrAttrgroupRelationEntity> relationEntities = aardao
                .selectList(null);
        //查出关联的分组属性
        List<AttrEntity> attrEntities = adao
                .selectList(new LambdaQueryWrapper<AttrEntity>()
                        .eq(AttrEntity::getCatelogId, catelogId));
        List<AttrGroupResVo> attrGroupResVos = new ArrayList<>();
        if (attrGroupEntities != null) {
            //复制到返回vo
            attrGroupResVos= attrGroupEntities.stream().map(resVo->{
                AttrGroupResVo attrGroupResVo=new AttrGroupResVo();
                BeanUtils.copyProperties(resVo, attrGroupResVo);
                return attrGroupResVo;
            }).collect(Collectors.toList());
            //给返回vo的attr添加值
            attrGroupResVos.forEach(entity->{
                List<AttrEntity> list=new ArrayList<>();
                for (AttrAttrgroupRelationEntity relationEntity : relationEntities) {
                    if(entity.getAttrGroupId().equals(relationEntity.getAttrGroupId())){
                        for (AttrEntity attrEntity : attrEntities) {
                            if(relationEntity.getAttrId().equals(attrEntity.getAttrId())){
                                list.add(attrEntity);
                            }
                        }
                    }
                }
                entity.setAttrs(list);
            });
        }
        return attrGroupResVos;
    }

}